package br.com.db;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.sanselan.ImageReadException;
import org.apache.sanselan.ImageWriteException;
import org.apache.sanselan.Sanselan;
import org.apache.sanselan.common.IImageMetadata;
import org.apache.sanselan.formats.jpeg.JpegImageMetadata;
import org.apache.sanselan.formats.tiff.TiffImageMetadata;
import org.apache.sanselan.formats.tiff.TiffImageMetadata.GPSInfo;
import org.xml.sax.SAXException;

public class TenRoundTest {

	/**
	 * @param args
	 * @throws IOException 
	 * @throws ImageWriteException 
	 */
	public static void main(String[] args) throws ImageWriteException, IOException {

		File folder = new File("C:\\georeferenced_images");
		File[] listOfFiles = folder.listFiles();
		
		long aggregateElapsedTime = 0;
		
		for (int i = 0; i < 10; i++) {
			
			cleanUpTags();
			
			ExecutorService executor = Executors.newFixedThreadPool(10);
			
			long startTime = System.nanoTime();    

			for (File file : listOfFiles) {

				Runnable worker = new WorkerThreadTenRound(file);
				executor.execute(worker);
			}
			executor.shutdown();

			while (!executor.isTerminated()) {
			}
			
			long roundElapsedTime = (System.nanoTime() - startTime)/1000000000;
			aggregateElapsedTime += roundElapsedTime;

			System.out.println("Elapsed time for round " + String.valueOf(i+1) + ": " + roundElapsedTime + " seconds.");	
			
		}
		
		System.out.println("Mean elapsed time: " + aggregateElapsedTime/10 + " seconds.");
	}

	private static void cleanUpTags() throws ImageWriteException, IOException {
		File folder = new File("C:\\georeferenced_images");
		File[] listOfFiles = folder.listFiles();

		for (File file : listOfFiles) {
			
			try {
				PhotoIPTC photoIPTC = new PhotoIPTC(file);
				photoIPTC.clearIPTCKeyWords();
			} catch (ImageReadException e) {
				//System.out.println(file.getName() + " - Not a Valid JPEG File: doesn't begin with 0xffd8");
				e.printStackTrace();
			}

		}		
	}
}

class WorkerThreadTenRound implements Runnable {

	private File file;

	public WorkerThreadTenRound(File file) {
		this.file = file;
	}

	@Override
	public void run() {
		try {
			System.out.println("Generating tags for file: " + file.getName());
			file = generateTags(file);
		} catch (ImageReadException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ImageWriteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private File generateTags(File target) throws ImageReadException,
			IOException, InterruptedException, ExecutionException,
			SAXException, ParserConfigurationException, ImageWriteException {

		String latitude = "";
		String longitude = "";
		File jpegImageFile = target;

		// obter info de GPS da foto
		IImageMetadata metadata = Sanselan.getMetadata(jpegImageFile);
		JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
		if (null != jpegMetadata) {

			TiffImageMetadata exif = jpegMetadata.getExif();

			if (null != exif) {
				GPSInfo gpsInfo = exif.getGPS();
				latitude = new Double(gpsInfo.getLatitudeAsDegreesNorth())
						.toString();
				longitude = new Double(gpsInfo.getLongitudeAsDegreesEast())
						.toString();
			}
		}

		// obter tags do Flickr
		FlickrPoiEnricher fpe = new FlickrPoiEnricher(latitude, longitude);
		List<String> poiFLickrTags = fpe.getPoiFlickrTags(latitude, longitude);

		StringBuilder flickr_sb = new StringBuilder();
		for (String string : poiFLickrTags) {
			flickr_sb.append("'" + string + "', ");
		}

		System.out.println("Flickr tags for file " + target.getName() + ": "
				+ flickr_sb.toString());

		// obter tags do Wikimapia
		WikimapiaPoiEnricher wpe = new WikimapiaPoiEnricher(latitude, longitude);
		List<String> poiWikimapiaTags = wpe.getPoiWikimapiaTags(latitude,
				longitude);

		StringBuilder wikimapia_sb = new StringBuilder();
		for (String string : poiWikimapiaTags) {
			wikimapia_sb.append("'" + string + "', ");
		}

		System.out.println("Wikimapia tags for file " + target.getName() + ": "
				+ wikimapia_sb.toString());

		// reunir as tags numa lista
		ArrayList<String> newTags = new ArrayList<String>();
		for (String flickrTag : poiFLickrTags) {
			newTags.add(flickrTag);
		}
		for (String wikimapiaTag : poiWikimapiaTags) {
			newTags.add(wikimapiaTag);
		}
		// adicionar tag ALREADY_PROCESSED
		// newTags.add(ALREADY_PROCESSED);

		// adicionar as tags no IPTC da foto
		PhotoIPTC photoIPTC = new PhotoIPTC(jpegImageFile);
		photoIPTC.addIPTCKeyword(newTags);

		return photoIPTC.getFile();
	}

}
